<?php

/*
 * CopyRight  : (C)2012-2099 HaoTeam Inc.
 * Document   : App.php
 * Created on : 2021-2-27 16:50:30
 * Author     : Tiger <1192851302@qq.com>
 * Description: This is NOT a freeware, use is subject to license terms.
 *              这即使是一个免费软件,使用时也请遵守许可证条款,得到当时人书面许可.
 *              未经书面许可,不得翻版,翻版必究;版权归属 HaoTeam Inc;
 */

namespace app\api\controller\wechat;

use app\Request;
use think\facade\Cache;
use think\facade\Log;
use haoteam\service\UtilService;
use haoteam\service\EasyWeChatService;
use haoteam\service\SessionService;
use haoteam\service\WechatAppService;
use app\api\model\WechatUser;
use app\api\model\WechatApp;

/**
 * 
 * Class App
 * Tiger <1192851302@qq.com> 2021-2-27 16:50:30
 */
class App {
    //protected $middleware = [Auth::class];

    /**
     * 个人中心
     * @author Tiger <1192851302@qq.com>
     * @param Request $request
     * @param type $mid
     * @return type
     */
    public function user(Request $request, $mid) {
        return app('json')->successful($request->user());
    }

    /**
     * 获取小程序LOGO
     * @author Tiger <1192851302@qq.com>
     * @param Request $request
     * @param int $mid Description
     * @return type
     */
    public function logo(Request $request, $mid) {
        return app('json')->successful([
                    'logo_url' => WechatApp::getOne($mid, 'logo')
        ]);
    }

    /**
     * 小程序登录
     * @author Tiger <1192851302@qq.com>
     * @param Request $request
     * @param int $mid Description
     * @return type
     */
    public function auth(Request $request, $mid) {
        $post = UtilService::postMore([
                    'code',
                    'spread_spid',
                    ['login_type', 'routine']
        ]);

        if (empty($post['code'])) {
            return app('json')->fail('授权失败,参数有误');
        }

        $EasyWeChatService = EasyWeChatService::miniapp($mid);

        if ($post['code']) {
            try {
                $userInfoCong = $EasyWeChatService->auth->session($post['code']);
                $openId = $userInfoCong['openid'];
                $unionId = $userInfoCong['unionid'];
            } catch (\Exception $e) {
                Log::error('获取session_key失败', ['line' => $e->getLine(), 'message' => $e->getMessage()]);
                return app('json')->fail('获取session_key失败，请检查您的配置！', ['line' => $e->getLine(), 'message' => $e->getMessage()]);
            }
        }
        if (empty($openId)) {
            return app('json')->fail('openid获取失败');
        }
        $WechatUser = new WechatUser();
        //曾经注册过的
        $user = $WechatUser->where('openId', $openId)->find();

        if (empty($user)) {
            try {
                $userInfo['openId'] = $userInfo['openId'] ?? $openId;
                $userInfo['unionId'] = $userInfo['unionId'] ?? $unionId;
                $userInfo['spread_spid'] = $post['spread_spid'];
                $userInfo['login_type'] = $post['login_type'];
                $userInfo['mid'] = $mid;
                $userInfo['phone'] = null;
                $user = WechatUser::create($userInfo);
            } catch (\Exception $exc) {
                Log::error('注册入库失败', ['line' => $exc->getLine(), 'message' => $exc->getMessage()]);
                return app('json')->fail('注册失败', ['line' => $exc->getLine(), 'message' => $exc->getMessage()]);
            }
        } else {
            $user->unionId = $unionId ?? null;
            $user->save();
        }

        try {
            $token = $WechatUser->getToken('api');
            //写入登录
            SessionService::instance()->set(compact('user'), $token['token']);
        } catch (\Exception $exc) {
            Log::error('写入登录失败', ['line' => $exc->getLine(), 'message' => $exc->getMessage()]);
            return app('json')->fail($exc->getMessage());
        }
        return app('json')->successful('登陆成功！', ['userInfo' => $user, 'token' => $token['token'], 'expires_time' => $token['params']['exp']]);
    }

    /**
     * 绑定手机号
     * @author Tiger <1192851302@qq.com>
     * @param Request $request
     * @param type $mid
     * @return type
     */
    public function bind_phone(Request $request, $mid) {
        $post = UtilService::postMore([
                    'phone',
                    'iv',
                    'encryptedData',
                    'cache_key'
        ]);
        $user = $request->user();

        $user['phone'] = $post['phone'] ?? null;

        if (empty($user['phone'])) {
            $cache_key = '';
            if (!empty($post['cache_key'])) {
                $cache_key = $post['cache_key'];
            }
            $session_key = Cache::get('api_session_key_' . $cache_key);

            if (empty($session_key)) {
                return app('json')->make(410002, '获取session_key失败');
            }

            $EasyWeChatService = EasyWeChatService::miniapp($mid);
            try {
                //解密获取用户信息
                $_data = $EasyWeChatService->encryptor->decryptData($session_key, $post['iv'], $post['encryptedData']);
            } catch (\Exception $e) {
                return app('json')->fail($e->getMessage());
            }
            $user['phone'] = $_data['phoneNumber'];
        }

        if (empty($user['phone'])) {
            return app('json')->fail('验证失败,参数有误');
        }

        if (WechatUser::be(['mid' => $mid, 'phone' => $user['phone']])) {
            return app('json')->fail('验证失败,该号码已存在');
        }
        try {
            WechatUser::update([
                'phone' => $user['phone']
                    ], ['mid' => $mid, 'id' => $request->uid()]);
        } catch (\Exception $exc) {
            return app('json')->fail($exc->getMessage());
        }
        //更新用户资料
        SessionService::instance()->set(compact('user'), $request->token());

        return app('json')->successful('验证成功', ['phone' => $user['phone']]);
    }

    /**
     * 输出应用
     * @author Tiger <1192851302@qq.com>
     * @param Request $request
     * @param string $mid
     * @param string $nodes Description
     */
    public function run(Request $request, $mid, $nodes) {
        $appInfo = WechatApp::getMore($mid);
        $request->macro('miniappInfo', function() use(&$appInfo) {
            return $appInfo;
        });
        $request->macro('mid', function() use(&$appInfo) {
            return $appInfo['id'];
        });
        $request->macro('addon', function() use(&$appInfo) {
            return $appInfo['addon'];
        });
        return WechatAppService::instance()->run($nodes);
    }

    /**
     * 输出应用
     * @desc 需要登录
     * @author Tiger <1192851302@qq.com>
     * @param Request $request
     * @param string $mid
     * @param string $nodes Description
     * @return type
     */
    public function auth_run(Request $request, $mid, $nodes) {
        $appInfo = WechatApp::getMore($mid);
        $request->macro('miniappInfo', function() use(&$appInfo) {
            return $appInfo;
        });
        $request->macro('mid', function() use(&$appInfo) {
            return $appInfo['id'];
        });
        $request->macro('addon', function() use(&$appInfo) {
            return $appInfo['addon'];
        });

        return WechatAppService::instance()->run($nodes);
    }

    /**
     * 获取小程序码
     * @author Tiger <1192851302@qq.com>
     * @param Request $request
     * @param type $mid
     * @return type
     */
    public function code(Request $request, $mid) {
        $EasyWeChatService = EasyWeChatService::miniapp($mid);
        $scene = 'user_id=' . $request->uid();
        $response = $EasyWeChatService->app_code->getUnlimit($scene, [
            'page' => 'pages/index/index',
            'width' => 600,
        ]);
        // $response 成功时为 EasyWeChat\Kernel\Http\StreamResponse 实例，失败为数组或你指定的 API 返回类型
        // 保存小程序码到文件
        if ($response instanceof \EasyWeChat\Kernel\Http\StreamResponse) {
            $filename = $response->saveAs(public_path() . '/upload/miniapp', $mid . '_' . $request->uid() . '_code.png');
        }
        return app('json')->successful('获取成功', ['url' => $request->domain() . '/upload/miniapp/' . $filename]);
    }

}
